/***************************************************
> Copyright (C) 2024 ==KINGYI== All rights reserved.
> File Name: send1.c
> Author:cjy
> Mail: 
> Created Time: 2024年08月05日 星期一 15时49分49秒
***************************************************/
/* 通过消息队列进程a给b发送5个学员信息，b收到后显示。
         b给a回送收到信息，a收到后结束。
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>

struct msgbuf{
    long mtype;   // 消息类型
    char mtext[100]; 
};

typedef struct use{
    char name[10];
    int age;
    float score;
} STU;

int main(int argc, const char* argv[])
{
    char path[50] = {0};
    key_t key = 0; // 消息队列标识符
    int msgid = 0; // 消息队列 ID
    int ret = 0; // 函数返回值

    printf("请输入路径:");
    scanf("%s", path);

    key = ftok(path,1); // 使用 ftok 生成一个唯一的 key
    if (key == -1) {
        perror("ftok");
        exit(-1);    
    }

    msgid = msgget(key, IPC_CREAT | 0666); // 创建或获取消息队列
    if (msgid == -1) {
        perror("msgget");
        exit(-1);    
    }

    int count = 0;
    int flag = 0;
    int n;

    printf("请输入想存几个值:");
    scanf("%d", &n);

    while (flag == 0) {
        count ++;

        STU stu;
        printf("请输入age:");
        scanf("%d", &stu.age);
        printf("请输入name:");
        scanf("%s", stu.name);
        printf("请输入score:");
        scanf("%f", &stu.score);

        // 发送一条消息
        struct msgbuf msg;
        msg.mtype = 1;
        memcpy(msg.mtext, &stu, sizeof(STU));
        ret = msgsnd(msgid, &msg, sizeof(STU), 0);
        if (ret == -1) {
            perror("msgsnd");
            exit(-1);
        }

        if (count == n) {
            flag = 1;
        }
    }

    // 再单独发送完成标志
    struct msgbuf eofMsg;
    eofMsg.mtype = 1;
    memset(eofMsg.mtext, 0, sizeof(eofMsg.mtext));
    strcpy(eofMsg.mtext, "EOF");
    ret = msgsnd(msgid, &eofMsg, sizeof(eofMsg.mtext), 0);
    if (ret == -1) {
        perror("msgsnd");
        exit(-1);
    }

    // 接收确认消息
    struct msgbuf confirmMsg;
    memset(&confirmMsg, 0, sizeof(confirmMsg));
    ret = msgrcv(msgid, &confirmMsg, sizeof(struct msgbuf) - sizeof(long), 2, 0);
    if (ret == -1) {
        perror("msgrcv");
        exit(-1);
    }

    printf("接收到了确认消息: %s\n", confirmMsg.mtext);

    // 删除消息队列
    ret = msgctl(msgid, IPC_RMID, NULL);
    if (ret == -1) {
        perror("msgctl");
        exit(-1);
    }

    return 0;
}


